<?php

class lb_page{
	
	public $page;
	public $type;
	public $active;
	public $pid;
	public $type_id;
	public $template;
	public $css;
	public $print_css;
	
	public $errs = array();
	
	/**
	 * constructor of lb_page
	 * 
	 * @access	public
	 * @author	Omid Mottaghi
	 * @param	int	page id
	 */
	public function __construct($page_id=false){
		global $lb;
		
		// set page id
		if(!isset($_GET['page']) || !is_numeric($_GET['page'])){
			$_GET['page'] = 1;
		}
		
		if($page_id === false){
			$page_id = $_GET['page'];
		}
		$this->page = $page_id;
		
		if($this->page > 0){
			 $params = array (
				 array ($this->page, 'int')
			 );
			 
			 $query = 'SELECT p.active AS active, p.page_id AS page_id, pt.name AS type,
					   p.page_type_id AS type_id, p.template AS template, p.css AS css, p.print_css AS print_css
					   FROM
					   #__page p,
					   #__page_type pt
					   WHERE
					   p.id = #
					   AND  p.id = pt.id';
			 
			 $result = $lb['db']->query($query, $params);
		}else{
			$result['num_of_rows'] = 0;
		}
		
		// if user exist, set sessions
		if($result['num_of_rows'] > 0){
			$this->type 	= $result['rows'][0]['type'];
			$this->active 	= $result['rows'][0]['active'];
			$this->pid 		= $result['rows'][0]['page_id'];
			$this->type_id 	= $result['rows'][0]['type_id'];
			
			if(!$result['rows'][0]['template']){
				$result['rows'][0]['template'] = $lb['template'];
			}
			$this->template	= $result['rows'][0]['template'];
			
			if(!$result['rows'][0]['css']){
				$result['rows'][0]['css'] = $lb['main_css'];
			}
			$this->css 		= $result['rows'][0]['css'];
			
			if(!$result['rows'][0]['print_css']){
				$result['rows'][0]['print_'] = $lb['print_css'];
			}
			$this->print_css = $result['rows'][0]['print_css'];
		}else{
			$this->type 	= false;
			$this->active 	= 1;
			$this->pid 		= 0;
			$this->type_id 	= false;
			$this->template = $lb['template'];
			$this->css		= $lb['main_css'];
			$this->print_css= $lb['print_css'];
		}
	}
	
	/**
	 * generate and set content of menu pane
	 * 
	 * @access	public
	 * @author	Omid Mottaghi
	 * @author	Armin Borumand
	 * @param 	boolean	this menu is writable for this user or not
	 * @return	boolean	if page has menu return true otherwise return false	
	 */
	public function generate_menu(){
		global $lb;
		
		$page_menu = false;
		// get menu links
		$link = 'CONCAT(\'' . $lb['webdir'] . 'index.php?page=\', id) link';
		
		/*
		$params = array (
			array ($this->page, 'int'),
		);
		
		$query = 'SELECT ' . $link . ', title
				FROM #__page WHERE page_id=#';
		$result = $lb['db']->query($query, $params);
		if($result['num_of_rows'] > 0){
			$lb['smarty']->assign ('list', $result['rows']);
			$page_menu = true;
		}
		
		// get parent link
		$params = array (
			array ($this->pid, 'int'),
		);
		$parent = $lb['db']->query('SELECT ' . $link . ', title
								FROM #__page WHERE id=#', $params);
		if($parent['num_of_rows'] > 0){
			$lb['smarty']->assign ('parent', $parent['rows'][0]);
			$page_menu = true;
		}

		// get family links
		$params = array (
			array ($this->pid , 'int'),
			array ($this->page, 'int')
		);
		$family = $lb['db']->query('SELECT ' . $link . ', title
								FROM #__page WHERE page_id = # AND id != #', $params);
		if($family['num_of_rows'] > 0){
			$lb['smarty']->assign ('family', $family['rows']);
			$page_menu = true;
		}
		*/
		
		$parent = array();
		$list   = array();
		$family = array();
		$query = 'SELECT id,
				 page_id,
				'. $link .',
				title 
			  FROM lb_page
				WHERE 
				page_id= # or
				id= # or
				page_id = #';
		$params = array(
				array($this->page, 'int'),
				array($this->pid,  'int'),
				array($this->pid,  'int')
				);
		$result = $lb['db']->query($query, $params);
		if($result['num_of_rows'] > 0){
			foreach($result['rows'] as $row){
				if($row['page_id'] == $this->page){
					$list[]   = $row;
				}elseif($row['id'] == $this->pid){
					$parent[] = $row;
				}elseif($row['page_id'] == $this->pid){
					$family[] = $row;
				}
			}
			$page_menu = true;
		}
		
		if(count($parent) > 0){
			$lb['smarty']->assign ('parent', $parent[0]);
		}
		if(count($list) > 0){
			$lb['smarty']->assign ('list'  , $list);
		}
		if(count($family) > 0){
			$lb['smarty']->assign ('family', $family);
		}
		
		return $page_menu;
	}

	/**
	 * Replace wiki codes with html tags
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	string	text to be processed
	 * @return	string	processed text!! 
	 */
	public function wikicode($text){
		global $lb;
		
		$text = preg_replace('/\[\[(.+)\]\]/U', "<a href=\"" . $lb['webdir'] .
				     "?title=\\1\">\\1</a>",$text);
		return stripslashes($text);
	}
	
	/**
	 * Add a new page to system database
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @author 	Omid Mottaghi
	 * @param	string	page type
	 * @param	string	page type id
	 * @param	string	page title
	 * @param	boolean	permission to write
	 * @param	int		page id
	 * @return	boolean	true on success and false on failure
	 */
	public function add_page($type, $add_type_id, $title, $write, $page_id=false, $parent_id=false){
		global $lb;
		
		if(self::check_title($title)){
			$this->errs[] = LANG_PAGE_ERROR_DUPLICATE_TITLE;
			return false;
		}
		
		if($title == ''){
			$this->errs[] = LANG_PAGE_ERROR_EMPTY_TITLE;
			return false;
		}
		
		// get all type of plugins
		$pages = $this->list_pages();
		
		if(!$add_type_id || !is_array($pages[$type])){
			return false;
		}
		
		if($parent_id === false){
			$parent_id = $this->page;
		}
		
		if($page_id === false){
			$params = array (
					array ($add_type_id	,'int'),
					array ($this->page	,'int'),
					array ($title		,'text')
					);
			$query = 'INSERT INTO #__page
					(page_type_id, page_id, title)
					VALUES
					(#, #, #)';
		}else{
			$params = array (
					array ($page_id		,'int'),
					array ($add_type_id	,'int'),
					array ($parent_id	,'int'),
					array ($title		,'text')
					);
			$query = 'INSERT INTO #__page
					(id, page_type_id, page_id, title)
					VALUES
					(#, #, #, #)';			
		}
		$result = $lb['db']->query($query, $params);
		$backparams[] = array (
					array ($add_type_id	,'int')
					);
		$backquery[] = 'DELETE FROM #__page
				WHERE page_type_id = #';
		if($result['num_of_rows'] < 1){
			return false;
		}
		$add_page_id = $result['insert_id'];
		
		$params = array (
				array ($type		, 'text'),
				array ($add_page_id	, 'int')
				);
		$query = 'INSERT INTO #__page_type
				(name, id)
				VALUES
				(#, #)';
		$result = $lb['db']->query($query, $params);
		$backparams[] = array (
					array ($add_page_id	,'int')
				);
		$backquery[] = 'DELETE FROM #__page_type
				WHERE id = #';
						
		if($result['num_of_rows'] < 1){
			$this->_undo_add_page($backquery, $backparams);
			return false;
		}
		
		if($write){
			$permis = 'write';
		}else{
			$permis = 'read';
		}
		
		$params = array (
					array ($add_page_id		, 'int'),
					array ($lb['user']->group_id()  , 'int'),
					array ($permis			, 'text')
				);
		$query = 'INSERT INTO #__pagegroup
				(page_id, group_id, type)
				VALUES
				(#, #, #)';
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] < 1){
			$this->_undo_add_page($backquery, $backparams);
			return false;
		}
		
		//Add to log
		self::add_change_log($add_page_id, $lb['user']->user_id, 'add');
		
		return $add_page_id;
	}
	
	/**
	 * Change page parent
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	int	new parent id
	 * @return	boolean	True on succes and false on failure
	 */
	public function move_page($to){
		global $lb;
		
		$params = array(
				array($to	 , 'int'),
				array($this->page, 'int')
				);
		$query = 'UPDATE #__page 
				SET page_id=# 
				WHERE id=#';
		$result = $lb['db']->query($query, $params);
									
		if($result['num_of_rows'] == 1){
			//Add to log
			self::add_change_log($this->page, $lb['user']->user_id, 'move');
			
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * Remove page from system databse
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	integer	page id
	 * @return	boolean	true on success and false on failure
	 */
	public function remove_page($page=false){
		global $lb;
		
		if($page === false){
			$page = $this->page;
		}
		
		$params = array(
				array($page	, 'int'),
				array($page	, 'int'),
				array($page	, 'int')
				);
		$query = 'DELETE A, B, C
				FROM #__page AS A,
					 #__page_type AS B,
					 #__pagegroup AS C
				WHERE
					A.id = # AND
					B.id = # AND
					C.page_id = #';
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] < 1){
			return false;
		}else{
			// Childs new parent = godparent
			$params = array(
					array($lb['page']->pid	, 'int'),
					array($lb['page']->page	, 'int')
					);
			$lb['db']->query('UPDATE #__page SET page_id = # WHERE page_id = #',$params);
			
			//Add to log
			self::add_change_log($page, $lb['user']->user_id, 'remove');
			
			return true;
		}
	}
	
	/**
	 * Edit page in database
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	string	page title
	 * @param	string	page id
	 * @return	boolean	true on success and false on failure
	 */
	public function edit_page($title, $page_id=false){
		global $lb;
		
		if($title == ''){
			$this->errs[] = LANG_PAGE_ERROR_EMPTY_TITLE;
			return false;
		}
		
		if($page_id == false){
			$page_id = $this->page;
		}
		$check_title = self::check_title($title);
		
		if($check_title != false && $check_title != $page_id ){
			$this->errs[] = LANG_PAGE_ERROR_DUPLICATE_TITLE;
			return false;
		}
		
		$params = array(
				array($title	, 'text'),
				array($page_id  , 'int')
				);
		$result = $lb['db']->query('UPDATE #__page SET title = # WHERE id = #', $params);
		
		if($result['num_of_rows'] < 0){
			return false;
		}else{
			//Add to log
			self::add_change_log($page_id, $lb['user']->user_id, 'edit');
			
			return true;
		}
	}
	
	/**
	 * delete added page data in database
	 *
	 * @access	protected
	 * @author Armin Borumand
	 * @param	array	insert queries
	 * @param	array	insert params
	 * @return	boolean
	 *
	 * @see	add_page()
	 */
	protected function _undo_add_page($queries, $params){
		global $lb;
		
		$i = 0;
		$num = count($queries);
		
		if( $num != count($params)){
			return false;
		}
		
		foreach($queries as $query){
			$result = $lb['db']->query($query, $params[$i++]);
		}
		
		return true;
	}
	
	/**
	 * return page id from type id and name
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	int/array	page type id
	 * @param	string	page type
	 * @return	array		page id
	 */
	public function get_id($type_id, $type){
		global $lb;
		$conds = '';
		$return = array();
		
		if(!is_array($type_id)){
			$type_id = array($type_id);
		}

		foreach($type_id as $v){
			$params[] = array($v, 'int');
			$conds .= 'T1.page_type_id = # or ';
		}

		$conds = substr($conds, 0, strlen($conds)-3);
		
		$params[] = array($type		, 'string');
		$result = $lb['db']->query('SELECT T1.id id,T1.page_type_id type_id
						FROM #__page AS T1,#__page_type AS T2 
						WHERE (' . $conds . ') AND T1.id=T2.id AND T2.name = #'
					   , $params);
		
		if($result['num_of_rows'] < 1){
			return false;
		}
		
		
		for($i = 0; $i < $result['num_of_rows']; $i++){
			$return[$result['rows'][$i]['type_id']] = $result['rows'][$i]['id'];
		}		
		return $return;
	}
	
	/**
	 * search in pages, call plugin search or system title search for giving search result
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	string	search page
	 * @param	array	search words
	 * @param	int		limit start row
	 * @param	int		number of results
	 * @param	string	search position(title or plugin)
	 * @return	array	consist of page title and ids
	 */
	public function search($page, $arr, $start, $number, $where){
		global $lb;
		
		$search_query_num = count($arr);
		for($i=0; $i<$search_query_num; $i++){
			$arr[$i] = str_replace(array('_', '*'), array(' ', '_'), $arr[$i]);
		}

		if($where == 'title'){
			return lb_page::search_title($page, $arr, $start, $number);
		}
		
		$lb_classes = lb_system::get_declared_classes();
		$sys_pages  = lb_page::list_pages();
		
		if(array_key_exists($page, $sys_pages) == false){
		
			$result['num_of_rows']	= -1;
			$result['rows']			= array();
			
		}else{
		
			if(in_array($sys_pages[$page]['class'], $lb_classes) == false){
				include($lb['dir'] . 'page/' . $sys_pages[$page]['path'] . '/' .
					$sys_pages[$page]['class'] . '.inc.php');
			}
			
			eval('$result = ' . $sys_pages[$page]['class'] . '::search($arr, $start, $number);');
		}
		
		return $result;
	}

	/**
	 * Search in titles, store search result in self::$search_archive
	 * future: we must use a database for storing search result and refere to search result by an individual id
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @author 	Omid Mottaghi
	 * @param	array		search pages
	 * @param	array		search words
	 * @param	int		limit start row
	 * @param	int		number of results
	 * @return	array		consist of page title and ids	
	 */
	public function search_title($pages, $arr, $start, $number){
		global $lb;
		
		
		if( !is_array($pages) ){
			$pages = array ($pages);
		}
		
		//Setting condition for INNER JOIN in the sql query for page type filtering
		
		$inner_cond = '';
		foreach($pages as $page){
			$params[] = array($page, 'text');
			$inner_cond .= 'pgt.name = # OR ';
		}
		$inner_cond = substr($inner_cond, 0, strlen($inner_cond) - 3);
		
		//Setting condition for WHERE in the sql query for page finding
		
		$conds = '';
		foreach($arr as $val){
			$params[] = array('%' . $val[1] . '%', 'text');
			$conds .= 'pg.title like # ' . $val[0].' ';
		}
					
		$conds = substr($conds, 0, strlen($conds) - 3);
		
		//Setting LIMIT ranges
		
		$params[] = array($start,	'int');
		$params[] = array($number,	'int');
		
		//double use!
		$params = array_merge($params, $params);
		array_pop($params);
		array_pop($params);
		
		$query = 'SELECT pg.id ,pg.title
			FROM #__page AS pg
				INNER JOIN #__page_type AS pgt
				ON pg.id = pgt.id AND (' . $inner_cond . ')
			WHERE ' . $conds . ' LIMIT #,# 
			UNION SELECT count(pg.id), NULL
				FROM #__page AS pg
					INNER JOIN #__page_type AS pgt
					ON pg.id = pgt.id AND (' . $inner_cond . ')
				WHERE ' . $conds;
		$result = $lb['db']->query($query, $params);

		//if there are an error in database result
		if($result['num_of_rows'] < 1){
			$result['rows'] = array();
		}
		
		if($result['num_of_rows'] - 1 < $number){
			$number = $result['num_of_rows'] - 1;
		}
		
		$result['num_of_rows'] = intval($result['rows'][$number]['id']);
		array_pop($result['rows']);
		
		return $result;
	}
	
	/**
	 * get all type of plugins
	 *
	 * @access	public
	 * @author	Omid Mottaghi
	 * @return	array		install pages
	 */
	public function list_pages(){
		global $lb;	
		$pages = lb_system::list_dir($lb['dir'] . 'page/');
		
		for($i = 0; isset($pages[$i]); $i++){
			include($lb['dir'] . 'page/' .$pages[$i] . '/motif.php');
			
			$sys_pages[$page_name]['path']	= $pages[$i];
			$sys_pages[$page_name]['desc']  = $page_desc;
			$sys_pages[$page_name]['class'] = $page_class;
		}
		
		//var_dump($sys_pages);
		return $sys_pages;
	}
	
	/**
	 * Change page type 
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	int		page id
	 * @param	string	new type name
	 * @param	int		new type id
	 * @return	boolean	true or false
	 */
	public function edit_type($page_id, $new_type, $new_type_id, $new_title=''){
		global $lb;
		
		$query = 'UPDATE #__page AS A, #__page_type AS B
				SET A.page_type_id = #';
		$params[] = array($new_type_id, 'int');
		
		if($new_title != ''){
			$query .= ' ,A.title = #';
			$params[] = array($new_title, 'text');
		}
		
		$query .= ',B.name = #
			   WHERE A.id = # AND B.id = #';

		array_push($params, 
				array($new_type, 'text'),
				array($this->page, 'int'),
				array($this->page, 'int')
			);
		
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] > 0){
			return true;
		}else{
			return false;
		}	
	}

	/**
	 * Change page group and permission 
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	int		page id
	 * @param	int		new group id
	 * @param	boolean	page permission
	 * @return	boolean	true or false
	 */
	public function edit_group($page_id, $new_group_id, $new_perm=NULL){
		global $lb;
		
		$params[] = array($new_group_id, 'int');
		$query	  = 'UPDATE #__pagegroup 
				SET group_id = # ';
					
		if($new_perm != NULL){
		
			if($new_perm == true){
				$perm = 'write';
			}else{
				$perm = 'read';
			}
			
			$params[] = array($perm, 'text');
			$query	 .= ',type = # ';
		}
		
		$params[] = array($page_id, 'int');
		$query	 .= 'WHERE page_id = #';
		
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] == 1){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * Return number of pages
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @return	int	number of pages
	 */
	public function count(){
		global $lb;
		
		$result = $lb['db']->query('SELECT count(*) AS count FROM #__page', array());
		
		if($result['num_of_rows'] > 0){
			return $result['rows'][0]['count'];
		}else{
			return -1;
		}
	}
	
	/**
	 * Return lb_page errors
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @return	array		lb_page errors
	 */
	public function get_errors(){
		$errors = $this->errs;
		$this->errs = array();
		return $errors;
	}

	/**
	 * Check title exists
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	string	page title
	 * @return	boolean	page id if title exists and false if not
	 */
	public function check_title($title){
		global $lb;
		
		$query  = 'SELECT id FROM #__page WHERE title = #';
		$params = array(
				array($title, 'text')
				);
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] > 0){
			return $result['rows'][0]['id'];
		}else{
			return false;
		}
	}
	
	
	/**
	 * Add a row to page change log
	 *
	 * @access	protected
	 * @author	Armin borumand
	 * @param	int		page id
	 * @param	int		user id
	 * @param	string	action
	 * @return	boolean	true on success and false on failure
	 */
	protected function add_change_log($page_id, $user_id, $action){
		global $lb;
		
		$query  = 'INSERT INTO #__page_log 
				(page_id, user_id, action, time)
				VALUES 
				(#, #, #, NOW())';
		
		$params =  array(
				array($page_id, 'int'),
				array($user_id, 'int'),
				array($action,	'text')
				);
					
		$result = $lb['db']->query($query, $params);
		
		if($result['result']){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * Return rows from change log
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	int		page id
	 * @param	int		number of last rows (if limit <= 0 return first change row)
	 * @return	resource	mysql result
	 */
	public function get_change_log($page_id, $limit){
		global $lb;
		
		$query  = 'SELECT A.action, A.time, B.username 
				  FROM #__page_log AS A
					INNER JOIN #__user AS B 
					ON (A.user_id = B.user_id)
				  WHERE page_id = #
				  ';
		$params = array(
				array($page_id, 'int')
				);
		
		//First action on the page
		if($limit <= 0){
			$query	 .= ' ORDER BY time LIMIT 1'; 
		}else{
			$query	 .= ' ORDER BY time DESC LIMIT 0,#';
			$params[] = array($limit, 'int');
		}
		
		$result = $lb['db']->query($query, $params);
		if($result['num_of_rows'] > 0){
			lb_system::make_time($result['rows'][0]['time']);
			return $result['rows'];
		}else{
			return false;
		}
	}
	
	/**
	 * Clean old rows from log
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @param	int		old age!
	 * @param	int		page id
	 * @return	boolean	true on success and false on failure
	 */
	public function clean_change_log($time, $page_id=false){
		global $lb;
		
		$query  = 'DELETE FROM #__page_log 
				WHERE time < TIMESTAMP(NOW() - #)';
		$params = array(
				array($time, 'int')
				);
					
		if($page_id){
			$query 	 .= ' AND page_id = #';
			$params[] = array($page_id, 'int');
		}
		
		$result = $lb['db']->query($query, $params);
		
		if($result['result']){
			return true;
		}else{
			return false;
		}
	}
}
?>
